#include <set>

#include <QList>
#include <QRemoteObjectHost>
#include <QThread>
#include <QIODevice>

#include <QtCore/private/QObject_p.h>
#include <private/qobject_p.h>

#include "QRO_p.h"
#include "QROHost.h"
#include "QRemoteObject2Meta_P.h"
#include "QRemoteFunction.h"
#include "./private/QROHost_P.h"

#include <rep_RemoteInterface_source.h>

void QROHost::start(QString url)
{
    _P->onStart(url);
}

void QROHost::registerObject(QObject *obj)
{
    _P->onRegisterObject(obj);
}

void QROHost::unregisterObject(QObject *obj)
{
    _P->onUnregisterObject(obj);
}

void QROHost::setDelegate(QROHostDelegate *delegate)
{
    _P->m_delegate = delegate;
}

QROHostDelegate* QROHost::delegate()
{
    return _P->m_delegate;
}

QList<QROClient *> QROHost::clients()
{
    QList<QROClient *> ret;

    for(auto i:_P->m_channels)
    {
        ret << i.second->client;
    }
    return ret;
}

void QROHost::updateProperty()
{
    _P->onUpdateProperty();
}

void QROHost::markPropertyModify(QObject *o, int index)
{
    _P->onMarkPropertyModify(o,index);
}

QROHost::QROHost():_P(new Private(this))
{
    connect(this,&QROHost::objectOnline,[](QObject* obj){
        auto item = dynamic_cast<QRemoteFunction*>(obj);
        if(item)
        {
            item->onOnline();
        }
    });

    connect(this,&QROHost::objectOffline,[](QObject* obj){
        auto item = dynamic_cast<QRemoteFunction*>(obj);
        if(item)
        {
            item->onOffline();
        }
    });

}

QROHost::~QROHost()
{
    delete _P;
}

void QROHost::activeMethod(QObject* target, int method, QVariantList param,QRemoteObject2::InvokeCallBack callBack)
{
    _P->onActiveMethod(target,method,param,callBack);
}

void QROHost::pushProperty(QObject *target, int prop, QVariant value)
{
    _P->onPushProperty(target,prop,value);
}

void QROHost::pushParent(QObject* target,QObject* parent)
{
    _P->onPushParent(target,parent);
}

void QROHost::occupyObject(QObject *target)
{
    _P->onOccupyObject(target);
}

void QROHost::releaseObject(QObject *target)
{
    _P->onReleaseObject(target);
}
